package cn.sky.demo.utils;

// LoanCalculatorUtils.java
public class LoanCalculatorUtils {
    
    /**
     * 等额本息计算结果
     */
    public static class EqualPrincipalInterestResult {
        private double totalMoney;
        private double totalInterests;
        private double[][] detail;
        
        public EqualPrincipalInterestResult(double totalMoney, double totalInterests, double[][] detail) {
            this.totalMoney = totalMoney;
            this.totalInterests = totalInterests;
            this.detail = detail;
        }
        
        // getters
        public double getTotalMoney() { return totalMoney; }
        public double getTotalInterests() { return totalInterests; }
        public double[][] getDetail() { return detail; }
    }
    
    /**
     * 等额本金计算结果
     */
    public static class EqualPrincipalResult {
        private double totalMoney;
        private double totalInterests;
        private double[][] detail;
        
        public EqualPrincipalResult(double totalMoney, double totalInterests, double[][] detail) {
            this.totalMoney = totalMoney;
            this.totalInterests = totalInterests;
            this.detail = detail;
        }
        
        // getters
        public double getTotalMoney() { return totalMoney; }
        public double getTotalInterests() { return totalInterests; }
        public double[][] getDetail() { return detail; }
    }
    
    /**
     * 等额本息计算方法
     */
    public static EqualPrincipalInterestResult calculateEqualPrincipalInterest(
            double loanMoney, int years, double yearInterest) {
        
        double monthInterest = yearInterest / 100 / 12;
        int months = years * 12;
        double pow = Math.pow(1 + monthInterest, months);
        double remains = loanMoney;
        
        double totalMoney = (months * loanMoney * monthInterest * pow) / (pow - 1);
        totalMoney = Math.floor(totalMoney * 100 + 0.5) / 100;
        
        double totalInterests = totalMoney - loanMoney;
        totalInterests = Math.floor(totalInterests * 100 + 0.5) / 100;
        
        double[][] detail = new double[months][3];
        for (int i = 0; i < months; i++) {
            if (i == months - 1) {
                detail[i][1] = remains * monthInterest;
                detail[i][1] = Math.floor(detail[i][1] * 100 + 0.5) / 100;
                detail[i][0] = remains;
                detail[i][0] = Math.floor(detail[i][0] * 100 + 0.5) / 100;
                detail[i][2] = detail[i][0] + detail[i][1];
                detail[i][2] = Math.floor(detail[i][2] * 100 + 0.5) / 100;
                break;
            }
            detail[i][1] = remains * monthInterest;
            detail[i][1] = Math.floor(detail[i][1] * 100 + 0.5) / 100;
            detail[i][2] = totalMoney / months;
            detail[i][2] = Math.floor(detail[i][2] * 100 + 0.5) / 100;
            detail[i][0] = detail[i][2] - detail[i][1];
            detail[i][0] = Math.floor(detail[i][0] * 100 + 0.5) / 100;
            remains -= detail[i][0];
        }
        
        return new EqualPrincipalInterestResult(totalMoney, totalInterests, detail);
    }
    
    /**
     * 等额本金计算方法
     */
    public static EqualPrincipalResult calculateEqualPrincipal(
            double loanMoney, int years, double yearInterest) {
        
        double monthInterest = yearInterest / 100 / 12;
        int months = years * 12;
        double remains = loanMoney;
        double sum = 0;
        
        double[][] detail = new double[months][3];
        for (int i = 0; i < months; i++) {
            detail[i][0] = loanMoney / months;
            detail[i][0] = Math.floor(detail[i][0] * 100 + 0.5) / 100;
            detail[i][1] = remains * monthInterest;
            detail[i][1] = Math.floor(detail[i][1] * 100 + 0.5) / 100;
            remains -= detail[i][0];
            detail[i][2] = detail[i][0] + detail[i][1];
            detail[i][2] = Math.floor(detail[i][2] * 100 + 0.5) / 100;
            sum += detail[i][2];
        }
        
        double totalMoney = Math.floor(sum * 100 + 0.5) / 100;
        double totalInterests = Math.floor((totalMoney - loanMoney) * 100 + 0.5) / 100;
        
        return new EqualPrincipalResult(totalMoney, totalInterests, detail);
    }
}
